namespace Effector {
    [GtkTemplate (ui="/de/grindhold/effector/ui/mainwindow.ui")]
    public class MainWindow : Gtk.ApplicationWindow {
        private GtkFlow.NodeView nv;

        public MainWindow() {
            this.nv = new GtkFlow.NodeView();
            this.nv_scroll.add(this.nv);

            Gtk.TreeIter iter;
            foreach (var name in Gegl.list_operations() ) {
                this.operation_store.append(out iter);
                this.operation_store.set(iter, 0, null, 1, name.dup());
            }

            Gtk.TargetEntry[] empty = {};
            this.operation_view.enable_model_drag_source(
                Gdk.ModifierType.BUTTON1_MASK,
                empty,
                Gdk.DragAction.COPY
            );
            this.operation_view.drag_data_get.connect(this.cb_drag_operation);
            Gtk.drag_source_add_text_targets(this.operation_view);


            Gtk.drag_dest_set(this.nv, Gtk.DestDefaults.ALL, empty, Gdk.DragAction.COPY);
            this.nv.drag_data_received.connect(this.cb_create_node);
            Gtk.drag_dest_add_text_targets(this.nv);

            this.show_all();
        }

        private void cb_drag_operation(Gdk.DragContext ctx, Gtk.SelectionData data, uint info, uint time_) {
            var selected_path = this.operation_view.get_selected_items().nth_data(0);
            var m = this.operation_view.get_model();
            Gtk.TreeIter treeiter;
            m.get_iter(out treeiter, selected_path);
            GLib.Value name;
            m.get_value(treeiter, 1, out name);
            data.set_text(name.get_string(),-1);
        }

        private void cb_create_node(Gdk.DragContext ctx, int x, int y, Gtk.SelectionData data, uint info, uint time_) {
            var node = new Effector.Node(data.get_text());
            this.nv.add_with_child(node,node.grid);
            this.nv.set_node_position(node, x, y);
            this.nv.show_types = false;
        }

        [GtkChild]
        private Gtk.IconView operation_view;
        [GtkChild]
        private Gtk.ListStore operation_store;

        [GtkChild]
        private Gtk.ScrolledWindow nv_scroll;

        [GtkCallback]
        public bool cb_quit() {
            Gtk.main_quit();
            return false;
        }

        public static void run() {
            new MainWindow();
            Gtk.main();
        }
    }

    public static int main(string[] argv) {
        Gtk.init(ref argv);
        Gegl.init(ref argv);

        MainWindow.run();

        return 0;
    }
}
